package com.ruoyi.app.handler;

import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson2.JSON;
import com.ruoyi.app.model.ActType;
import com.ruoyi.fapp.model.WsInfo;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.fapp.service.AppChatMsgService;
import com.ruoyi.framework.web.service.TokenService;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.group.ChannelGroup;
import io.netty.channel.group.DefaultChannelGroup;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import io.netty.util.concurrent.GlobalEventExecutor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@ChannelHandler.Sharable
@Component
public class WebSocketFrameHandler extends SimpleChannelInboundHandler<TextWebSocketFrame> {

    // 存储所有连接的客户端
    private static final ChannelGroup channels = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);


    @Autowired
    TokenService tokenService;

    @Autowired
    AppChatMsgService appChatMsgService;

    @Autowired
    private RedisCache redisCache;

    @Override
    public void handlerAdded(ChannelHandlerContext ctx) {

        System.out.println("handlerAdded：" + ctx.channel().id());

        channels.add(ctx.channel());


    }

    @Override
    public void handlerRemoved(ChannelHandlerContext ctx) {
        System.out.println("handlerAdded：" + ctx.channel().id());
        channels.remove(ctx.channel());
    }

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, TextWebSocketFrame msg) {
        if (msg == null) {
            // 记录异常并关闭连接
            ctx.close();

            return;
        }

        String request = msg.text();
        System.out.println("收到客户端消息：" + request);
        System.out.println("channelRead0：" + ctx.channel().id());

        //验证用户是否登录
        String actType = JSONUtil.parseObj(request).getStr("actType");

        if (actType.equals(ActType.WS_LOGIN.getValue())) { //登录

            String token = JSONUtil.parseObj(request).getStr("token");
            String userKey = tokenService.getUserKeyFromToken(token.replace(Constants.TOKEN_PREFIX, ""));
            LoginUser user =null;
           if(null != userKey) {
               user = redisCache.getCacheObject(userKey);
           }
            //验证token 是否有效 jwt
            if (user != null) { //有效
                System.out.println("客户端Ws 验证成功：" + user.getUsername());
                ctx.channel().writeAndFlush(new TextWebSocketFrame(JSON.toJSON(AjaxResult.success("---登录成功---")).toString()));
            } else {

                System.out.println("客户端Ws 验证失败：");
                // JSON.toJSON(AjaxResult.error(401,"登录失败"));
                ctx.channel().writeAndFlush(new TextWebSocketFrame(JSON.toJSON(AjaxResult.error(401, "登录失败")).toString()));
                channels.remove(ctx.channel());
                return;
            }

            //todo 其他前置校验
            ;

        } else if (actType.equals(ActType.WS_MSG.getValue())) { //发送消息

            //添加一条记录 todo 考虑加入消息队列
           // WsInfo JSONUtil.parseObj(request)
           // AppMessage
         //appChatMsgService.addChat();

            WsInfo wsInfo = JSONUtil.toBean(request, WsInfo.class);
            appChatMsgService.addChat(wsInfo);

            //传递给接受者



        } else if (actType.equals(ActType.WS_LOGOUT.getValue())) { //主动退出

        } else if (actType.equals(ActType.WS_HEARTBEAT.getValue())) { //心跳

            ctx.channel().writeAndFlush(new TextWebSocketFrame(JSON.toJSON(AjaxResult.success("响应成功")).toString()));
        }


        //ctx.channel().writeAndFlush(new TextWebSocketFrame("服务端回应：" + request));
    }

    // 可供外部调用发送消息
    public static void sendMessageToAll(String message) {
        channels.writeAndFlush(new TextWebSocketFrame(message));
    }
}
